package routers

import (
	"fmt"
	//"net/http"
	"TeacherManager/common"
	"TeacherManager/controllers"
	"TeacherManager/models"
	"TeacherManager/system"
	"html/template"
	"path/filepath"

	"github.com/cihub/seelog"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"github.com/utrack/gin-csrf"
)

func Init() *gin.Engine {
	//运行模式
	fmt.Println("-----------------")
	fmt.Println(system.GetConfiguration())
	gin.SetMode(system.GetConfiguration().Mode)

	r := gin.Default()

	setTemplate(r)
	setSessions(r)

	r.Use(SharedData())
	//路由配置
	set(r)
	return r
}

func setTemplate(r *gin.Engine) {

	funcMap := template.FuncMap{
		"dateFormat": common.DateFormat,
		"substring":  common.Substring,
		"isOdd":      common.IsOdd,
		"isEven":     common.IsEven,
		"truncate":   common.Truncate,
		"add":        common.Add,
		//"listtag":    common.ListTag,
	}

	r.SetFuncMap(funcMap)
	r.Static("/static", filepath.Join(getCurrentDirectory(), "./static"))
	r.LoadHTMLGlob(filepath.Join(getCurrentDirectory(), "./views/**/*"))

}

func setSessions(r *gin.Engine) {
	config := system.GetConfiguration()

	store := cookie.NewStore([]byte(config.SessionSecret))
	store.Options(sessions.Options{HttpOnly: true})
	r.Use(sessions.Sessions("gin-session", store))

	//mr := csrf.Middleware(csrf.Options{
	//	Secret: config.SessionSecret,
	//	ErrorFunc: func(c *gin.Context) {
	//		c.String(400, "CSRF token mismatch")
	//		c.Abort()
	//	},
	//})
	//r.Use(mr)
}

//上线时采取
//func getCurrentDirectory() string {
//	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
//
//	if err != nil {
//		seelog.Critical(err)
//	}
//
//	return strings.Replace(dir, "\\", "/", -1)
//}

//采用goland开发时采用这个
func getCurrentDirectory() string {
	return ""
}

func SharedData() gin.HandlerFunc {
	return func(c *gin.Context) {
		session := sessions.Default(c)
		if uID := session.Get(controllers.SESSION_KEY); uID != nil {
			user, err := models.GetUser(uID)
			if err == nil {
				c.Set(controllers.CONTEXT_USER_KEY, user)
			}
		}
		if system.GetConfiguration().SignupEnabled {
			c.Set("SignupEnabled", true)
		}
		c.Next()
	}
}

//func AuthRequired() gin.HandlerFunc {
//	return func(c *gin.Context) {
//		if user, _ := c.Get("User"); user != nil {
//			c.Next()
//		} else {
//			seelog.Warnf("User not authorized to visit %s", c.Request.RequestURI)
//			c.Redirect(http.StatusSeeOther, "/login")
//		}
//	}
//}
func DefindCsrf() gin.HandlerFunc {
	config := system.GetConfiguration()

	return csrf.Middleware(csrf.Options{
		Secret: config.SessionSecret,
		ErrorFunc: func(c *gin.Context) {
			c.String(400, "CSRF token mismatch")
			c.Abort()
		},
	})

}

func AdminScopeRequired() gin.HandlerFunc {
	return func(c *gin.Context) {
		if user, _ := c.Get(controllers.CONTEXT_USER_KEY); user != nil {
			if u, ok := user.(*models.User); ok && u.IsAdmin {
				c.Next()
				return
			}
		}
		seelog.Warnf("User not authorized to visit %s", c.Request.RequestURI)

		//c.HTML(http.StatusForbidden, "error/error.html", gin.H{
		//	"Isforbid": true,
		//})
		controllers.HandleForbid(c)
		c.Abort()
	}
}

//路由配置
func set(r *gin.Engine) {
	r.NoRoute(controllers.Handle404)
	r.GET("/", controllers.SigninGet)
	r.GET("/signin", controllers.SigninGet)
	//可以对其他postapi做csrf防御。
	r.POST("/signin", DefindCsrf(), controllers.SigninPost)
	r.GET("/logout", controllers.LogoutGet)
	if system.GetConfiguration().SignupEnabled {
		r.GET("/signup", controllers.SignupGet)
		r.POST("/signup", controllers.SignupPost)
	}

	authorized := r.Group("/admin")
	authorized.Use(AdminScopeRequired())
	{
		// index
		authorized.GET("/index", controllers.AdminIndex)
		//班级相关
		authorized.GET("/seeclass", controllers.SeeClass)
		authorized.POST("/createclass", controllers.CreateClass)
		authorized.POST("/class/delete", controllers.DeleteClass)
		authorized.GET("/managerclass", controllers.ManagerClass)
		authorized.GET("/getclasses", controllers.GetClasses)
		authorized.POST("/class/update", controllers.UpdateClass)
		authorized.POST("/getpubclass", controllers.GetPubClasses)
		//个人信息
		authorized.GET("/profile", controllers.ProfileGet)
		authorized.POST("/profile", controllers.ProfileUpdate)
		//邀请码
		authorized.GET("/getcode", controllers.GetInviteCode)
		//测试
		authorized.GET("/getexams", controllers.GetExams)
		authorized.POST("/Autoexam", controllers.AutoExam)
		authorized.POST("/exam/delete", controllers.DeleteExam)
		authorized.GET("/managerexam", controllers.ManagerExam)
		authorized.POST("/exam/update", controllers.UpdateExam)
		authorized.POST("/exam/unpublish", controllers.UnpublishExam)
		authorized.POST("/exam/save", controllers.SaveExam)
		//查看测试详情
		authorized.GET("/exam/:id", controllers.ExamGetByTeacher)
		//验证用户
		authorized.POST("/checkuser", controllers.CheckUser)

		//image upload
		//authorized.POST("/upload", controllers.Upload)

		// page
		//authorized.GET("/class", controllers.Class)
		//authorized.GET("/new_page", controllers.PageNew)
		//authorized.POST("/new_page", controllers.PageCreate)
		//authorized.GET("/page/:id/edit", controllers.PageEdit)
		//authorized.POST("/page/:id/edit", controllers.PageUpdate)
		//authorized.POST("/page/:id/publish", controllers.PagePublish)
		//authorized.POST("/page/:id/delete", controllers.PageDelete)

	}

	r.Run(system.GetConfiguration().Addr)
}
